package com.junjie.checkin.service;

import com.junjie.checkin.entity.TUser;
import com.junjie.checkin.exception.RoleErrorException;
import com.junjie.checkin.exception.UserAlreadyExistsException;
import com.junjie.checkin.mapper.UserMapper;
import com.junjie.checkin.response.auth.AuthResponse;
import com.junjie.checkin.response.auth.TokenResponse;
import com.junjie.checkin.response.auth.UserInfoResponse;
import com.junjie.checkin.security.exception.TokenInvalidException;
import com.junjie.checkin.security.exception.TokenOwnerException;
import com.junjie.checkin.security.service.AuthDetails;
import com.junjie.checkin.security.service.JwtService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * @author 洪浚杰
 * @description
 * @date 2025/6/9 13:50
 */
@Service
public class AuthService {
    private static final Logger logger = LoggerFactory.getLogger(AuthService.class);

    @Autowired
    RedisTemplate<String,Object> redisTemplate;
    @Autowired
    UserMapper userMapper;
    @Autowired
    PasswordEncoder encoder;
    @Autowired
    AuthenticationManager authenticationManager;
    @Autowired
    JwtService<TokenResponse,AuthDetails> jwtService;
    /**
     *  用户登录
     */
    public AuthResponse login(boolean isAdmin, String username, String password) {
        Authentication authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        AuthDetails authDetails = (AuthDetails) authenticate.getPrincipal();
        TUser user = authDetails.getUser();

        // 检查角色
        if (isAdmin) {
            if (user.getRole() != 1) {
                throw new RoleErrorException();
            }
        } else {
            if (user.getRole() != 0) {
                throw new RoleErrorException();
            }
        }

        // 删除旧的 token 和 refresh token
        String userTokenKey = "user_token:" + user.getId();
        String userRefreshKey = "user_refresh:" + user.getId();

        // 打印当前 key 的 value（用于确认是否存在）
        Object accessToken = redisTemplate.opsForValue().get(userTokenKey);
        Object refreshToken = redisTemplate.opsForValue().get(userRefreshKey);


        // 删除外层 key
        boolean tokenDeleted = redisTemplate.delete(userTokenKey);
        boolean refreshDeleted = redisTemplate.delete(userRefreshKey);


        if (accessToken != null) {
            redisTemplate.delete(accessToken.toString());
        }
        if (refreshToken != null) {
            redisTemplate.delete(refreshToken.toString());
        }

        // 生成新 token
        TokenResponse token = jwtService.createToken(authDetails);
        UserInfoResponse userInfo = new UserInfoResponse(user.getId(), user.getUsername(), user.getNickname(),user.getAvatar(), user.getRole() == 1);

        return new AuthResponse(userInfo, token);
    }


    /**
     * 注册用户
     * @param username 用户名
     * @param password 密码
     */
    public void register(String username,String password) {
        // 获取用户
        TUser u = userMapper.getUserByUsername(username);
        if (!Objects.isNull(u)){
            throw new UserAlreadyExistsException();
        }
        TUser user = new TUser();
        user.setUsername(username);
        user.setNickname(username);
        // 设置分数为0
        user.setScore(0);
        user.setPassword(encoder.encode(password));
        userMapper.insert(user);

    }

    /**
     * 更新访问令牌
     * @param refreshToken 更新令牌
     * @param id 用户ID
     * @return 新令牌
     */
    public TokenResponse refresh(String refreshToken,Integer id){
        // 检查redis中保持的redis的refreshToken是否符合
        String refreshKey = "refresh:"+refreshToken;
        Integer userId = (Integer)redisTemplate.opsForValue().get(refreshKey);

        // 调试
//        logger.info("Refresh token received: {}", refreshToken);
//        logger.info("User ID from request: {}", id);
//        logger.info("User ID from Redis: {}", redisTemplate.opsForValue().get("user_refresh:"+userId));

        // 检查token是否是有效的
        if (Objects.isNull(userId)){
            throw new TokenInvalidException();
        }
        // 检查申请更新的用户是否是该令牌对应的用户
        if (!userId.equals(id)){
            throw new TokenOwnerException();
        }
        // 清除掉redis中的refreshToken
        redisTemplate.delete(refreshKey);

        // 更新redis中的token数据,包括refreshToken
        TUser user = userMapper.selectById(userId);
        return jwtService.createToken(new AuthDetails(user));
    }

    /**
     * 登出
     * @param userId 用户ID
     */
    public void logout(Integer userId){
        // 清除掉redis中存储的token,包括refreshToken
        String userRefreshKey = "user_refresh:"+userId;
        String userTokenKey = "user_token:"+userId;
        String tokenKey = (String) redisTemplate.opsForValue().get(userTokenKey);
        String refreshKey = (String) redisTemplate.opsForValue().get(userRefreshKey);
        redisTemplate.delete(userRefreshKey);
        redisTemplate.delete(userTokenKey);
        redisTemplate.delete(tokenKey);
        redisTemplate.delete(refreshKey);

    }
}
